Skip to content

Conversation

@juntaowww
Copy link
Contributor

Summary

When specifying [Tests.nsys] in a scenario file to override only specific nsys configuration fields (like output), the entire nsys object was being overwritten instead of just the specified fields.

Fix:

"nsys": self.nsys.model_dump() if self.nsys else None,

to:

"nsys": self.nsys.model_dump(exclude_unset=True) if self.nsys else None,

Using exclude_unset=True ensures that only fields explicitly set by the user in the scenario file are included in the dump. The deep_merge function then correctly merges only those specified fields with the test configuration, preserving all other nsys settings from the test definition.

Test Plan

TestNsysMerging is added to tests/test_test_scenario.py for testing the correctness of overwriting of nsys fields from scenario configuration.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 2, 2026

📝 Walkthrough

Walkthrough

This PR changes nsys serialization to exclude unset fields during TestRunModel.tdef_model_dump and adds a new TestNsysMerging test suite (four tests) validating merging behavior of NsysConfiguration between base NCCLTestDefinition and scenario overrides.

Changes

Cohort / File(s) Summary
Model Serialization
src/cloudai/models/scenario.py
Serialize nsys with model_dump(exclude_unset=True) when present (previously default serialization); minor copyright year update.
Test Coverage
tests/test_test_scenario.py
Added TestNsysMerging with four tests: partial override, multiple-field override, scenario-only addition, and disable-override behavior for NsysConfiguration merging; added NsysConfiguration to public imports used in tests.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🐰 I hop through fields both set and free,
I hide the blanks where they shouldn't be.
Four tests I plant to check the blend,
Merge and tidy — then home I send.
✨🍃

🚥 Pre-merge checks | ✅ 2
✅ Passed checks (2 passed)
Check name Status Explanation
Title check ✅ Passed The title directly summarizes the main fix: correcting nsys subfield merging behavior in scenario file overrides.
Description check ✅ Passed The description clearly explains the bug, provides the exact code fix with before/after comparison, and documents the test plan.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

No actionable comments were generated in the recent review. 🎉


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@greptile-apps
Copy link
Contributor

greptile-apps bot commented Feb 2, 2026

Greptile Overview

Greptile Summary

Fixed nsys subfield merging behavior by using exclude_unset=True in model_dump() call. Previously, when users specified only specific nsys fields (like output) in a scenario file, the entire nsys object was being overwritten with default values for unset fields, causing configured fields from the base test definition to be lost.

  • Changed self.nsys.model_dump() to self.nsys.model_dump(exclude_unset=True) in src/cloudai/models/scenario.py:111
  • This ensures only explicitly set fields are included in the dump, allowing deep_merge to correctly preserve unspecified fields from the base configuration
  • Added comprehensive test suite TestNsysMerging with 4 test cases validating the fix for various scenarios
  • Updated copyright year to 2026 in both modified files

Confidence Score: 5/5

  • This PR is safe to merge with minimal risk
  • The fix is surgical (single parameter change), well-tested with comprehensive test coverage, and addresses a clear bug in the merging logic without affecting other functionality
  • No files require special attention

Important Files Changed

Filename Overview
src/cloudai/models/scenario.py Added exclude_unset=True to nsys model_dump() on line 111, ensuring only explicitly set fields are included during deep merge. Also updated copyright year to 2026.
tests/test_test_scenario.py Added comprehensive test suite TestNsysMerging with 4 test cases covering partial overrides, multiple field overrides, adding nsys to base without nsys, and disable override scenarios. Updated copyright year to 2026.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Fix all issues with AI agents
In `@tests/test_test_scenario.py`:
- Around line 520-653: Remove the behavioral docstrings inside the
TestNsysMerging test methods: delete the triple-quoted strings at the top of
test_nsys_partial_override_preserves_base_config,
test_nsys_multiple_fields_override, test_nsys_scenario_adds_to_base_without_nsys
(and any similar method docstrings such as test_nsys_disable_override) so the
tests only contain assertions and setup; leave any high-level
interface/class-level documentation if needed but strip per-test behavior
descriptions that duplicate the assertions.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

assert tdef.nsys.enable is True

def test_nsys_multiple_fields_override(self, test_scenario_parser: TestScenarioParser, slurm_system: SlurmSystem):
from cloudai.core import NsysConfiguration
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can it be imported on top of this file? (same for all tests)

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@juntaowww I assume you used an AI assistant to help you with the code. they really tend to bring imports deep inside. could you please share what is the assistant so we could prepare some common agents config (if there's such an option) to let the agent know about the code style?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Put them back on top of the file.

Indeed AI is used, could add some rules to prevent this in the future.

"cmd_args": self.cmd_args.model_dump(by_alias=by_alias) if self.cmd_args else None,
"git_repos": [repo.model_dump() for repo in self.git_repos] if self.git_repos else None,
"nsys": self.nsys.model_dump() if self.nsys else None,
"nsys": self.nsys.model_dump(exclude_unset=True) if self.nsys else None,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can't that lead to a dict without required fields set?

BTW, I think this is similar to what you did for reports. Maybe we should have a function merge_models(tdef, tscenario) or something like that? Do you think that will be useful?

Our current approach is "all or nothing", meaning that everything should be either set on one level or another. If we start doing smarter merge, I'd prefer we do it consistently. Overall this feels as a better and friendlier approach.

cc @podkidyshev

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

still learning, so my opinion should be rather optional here :)

  1. the change seems safe and positive. agree with Andrey that it would be nice to make it consistent across all model merges but I would assume it's on the cloudai dev team's shoulders

  2. Can't that lead to a dict without required fields set?

seems safe, if this is the risk you meant

>>> import pydantic
>>> from typing import Optional
>>> class A(pydantic.BaseModel):
...     model_config = pydantic.ConfigDict(extra='forbid')
...     a: str
...     b: Optional[str] = 'b'
... 
>>> A.model_validate({'b': '33'})
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "/Users/ipodkidyshev/projects/cloudai/.venv/lib/python3.10/site-packages/pydantic/main.py", line 705, in model_validate
    return cls.__pydantic_validator__.validate_python(
pydantic_core._pydantic_core.ValidationError: 1 validation error for A
a
  Field required [type=missing, input_value={'b': '33'}, input_type=dict]
    For further information visit https://errors.pydantic.dev/2.11/v/missing

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

BTW, I think this is similar to what you did for reports. Maybe we should have a function merge_models(tdef, tscenario) or something like that? Do you think that will be useful?

Yes this is similar to the case for reports. For merge_models I think we already have similar util function deep_merge(test_defined, tc_defined)? In tdef_model_dump here I think basically it defined the overriding logic, as values in tc_defined (returned by tdef_model_dump) has higher hierarchy to override values in test_defined. (Or maybe actually we could reverse the hierarchy? But this may create chaos)

Our current approach is "all or nothing", meaning that everything should be either set on one level or another. If we start doing smarter merge, I'd prefer we do it consistently. Overall this feels as a better and friendlier approach.

Indeed agreed.

Copy link
Contributor

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

2 files reviewed, no comments

Edit Code Review Agent Settings | Greptile

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants